package br.com.hd.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;

import org.richfaces.event.UploadEvent;
import org.richfaces.model.UploadItem;

import br.com.hd.constantes.Constantes;
import br.com.hd.dao.ChamadoDAO;
import br.com.hd.dao.DAO;
import br.com.hd.dao.ResponsavelDepartamentoDAO;
import br.com.hd.entity.Categoria;
import br.com.hd.entity.Chamado;
import br.com.hd.entity.Departamento;
import br.com.hd.entity.Prioridade;
import br.com.hd.entity.Responsavel;
import br.com.hd.entity.ResponsavelDepartamento;
import br.com.hd.entity.Status;
import br.com.hd.entity.Usuario;
import br.com.hd.util.EnviarEmail;

public class ChamadoController {

	private Chamado chamado;
	private Long segundoNivel = 1L;
	private List<Chamado> chamadoList = new ArrayList<Chamado>();
	private List<SelectItem> departamentos = new ArrayList<SelectItem>();
	private List<SelectItem> status = new ArrayList<SelectItem>();
	private List<SelectItem> categorias = new ArrayList<SelectItem>();
	private List<SelectItem> prioridades = new ArrayList<SelectItem>();

	public Chamado getChamado() {
		return chamado;
	}

	public void setChamado(Chamado chamado) {
		this.chamado = chamado;
	}

	public List<Chamado> getChamadoList() {
		return chamadoList;
	}

	public void setChamadoList(List<Chamado> chamadoList) {
		this.chamadoList = chamadoList;
	}

	public List<SelectItem> getDepartamentos() {
		return departamentos;
	}

	public void setDepartamentos(List<SelectItem> departamentos) {
		this.departamentos = departamentos;
	}

	public List<SelectItem> getStatus() {
		return status;
	}

	public void setStatus(List<SelectItem> status) {
		this.status = status;
	}

	public List<SelectItem> getCategorias() {
		return categorias;
	}

	public void setCategorias(List<SelectItem> categorias) {
		this.categorias = categorias;
	}

	public List<SelectItem> getPrioridades() {
		return prioridades;
	}

	public void setPrioridades(List<SelectItem> prioridades) {
		this.prioridades = prioridades;
	}

	public Long getSegundoNivel() {
		return segundoNivel;
	}

	public void setSegundoNivel(Long segundoNivel) {
		this.segundoNivel = segundoNivel;
	}

	public void cadastrar() throws IOException, ParseException {
		chamado = new Chamado();
		chamado.setDepartamento(new Departamento());
		chamado.setCategoria(new Categoria());
		chamado.setResponsavel(new Responsavel());
		chamado.setStatus(new Status());
		chamado.setUsuario(new Usuario());
		chamado.setPrioridade(new Prioridade());
		listarDepartamentos();
		buscarUsuarioLogado();
		listarPrioridades();
		FacesContext.getCurrentInstance().getExternalContext()
				.redirect("cadastrarChamado.jsp");
	}

	@SuppressWarnings("unchecked")
	public List<Chamado> listar() throws IOException {
		chamadoList = new ArrayList<Chamado>();
		chamadoList = DAO.getInstance().list(Chamado.class);
		FacesContext.getCurrentInstance().getExternalContext()
				.redirect("listarChamado.jsp");
		return chamadoList;
	}

	public void salvar() throws Exception {
		chamado.setResponsavel(null);
		chamado.setCategoria(null);
		Status status = new Status();
		status.setCodigo(Constantes.STATUS_AGUARDANDO);
		status = (Status) DAO.getInstance().refresh(status);
		chamado.setStatus(status);
		chamado.setDataInicio(new Date());
		chamado.setNivel(Constantes.NIVEL_UM);
		chamado.setDepartamento((Departamento) DAO.getInstance().refresh(
				chamado.getDepartamento()));
		DAO.getInstance().save(chamado);
		EnviarEmail e = new EnviarEmail();
		e.enviarEmailChamado(chamado);
		chamado = new Chamado();
		chamado.setDepartamento(new Departamento());
		chamado.setCategoria(new Categoria());
		chamado.setResponsavel(new Responsavel());
		chamado.setStatus(new Status());
		chamado.setUsuario(new Usuario());
		chamado.setPrioridade(new Prioridade());
	}

	public Chamado editar() throws IOException, ParseException {
		listarDepartamentos();
		listarStatus();
		listarCategorias();
		FacesContext context = FacesContext.getCurrentInstance();
		chamado = (Chamado) context.getExternalContext().getRequestMap()
				.get("list");
		buscarResponsavelLogado();
		if (chamado.getNivel().equals(Constantes.NIVEL_UM)) {
			chamado.getStatus().setCodigo(
					Constantes.STATUS_EM_ATENDIMENTO_1_NIVEL);
		}
		if (chamado.getNivel().equals(Constantes.NIVEL_DOIS)) {
			chamado.getStatus().setCodigo(
					Constantes.STATUS_EM_ATENDIMENTO_2_NIVEL);
		}
		ChamadoDAO.getInstance().updateNoMessage(chamado);
		chamado.setCategoria(new Categoria());
		FacesContext.getCurrentInstance().getExternalContext()
				.redirect("resolverChamado.jsp");
		return chamado;
	}

	public Chamado visualizar() throws IOException, ParseException {
		FacesContext context = FacesContext.getCurrentInstance();
		chamado = (Chamado) context.getExternalContext().getRequestMap()
				.get("list");
		FacesContext.getCurrentInstance().getExternalContext()
				.redirect("visualizarChamado.jsp");
		return chamado;
	}

	@SuppressWarnings("unchecked")
	public List<SelectItem> listarDepartamentos() {
		departamentos = new ArrayList<SelectItem>();
		List<Departamento> departamentoList = new ArrayList<Departamento>();
		departamentoList = DAO.getInstance().list(Departamento.class);
		for (Departamento departamento : departamentoList) {
			departamentos.add(new SelectItem(departamento.getCodigo(),
					departamento.getDescricao()));
		}
		return departamentos;
	}

	@SuppressWarnings("unchecked")
	public List<SelectItem> listarCategorias() {
		categorias = new ArrayList<SelectItem>();
		List<Categoria> categoriaList = new ArrayList<Categoria>();
		categoriaList = DAO.getInstance().list(Categoria.class);
		for (Categoria categoria : categoriaList) {
			categorias.add(new SelectItem(categoria.getCodigo(), categoria
					.getDescricao()));
		}
		return categorias;
	}

	@SuppressWarnings("unchecked")
	public List<SelectItem> listarStatus() {
		status = new ArrayList<SelectItem>();
		List<Status> statusList = new ArrayList<Status>();
		statusList = DAO.getInstance().list(Status.class);
		for (Status item : statusList) {
			status.add(new SelectItem(item.getCodigo(), item.getDescricao()));
		}
		return status;
	}

	@SuppressWarnings("unchecked")
	public List<SelectItem> listarPrioridades() {
		prioridades = new ArrayList<SelectItem>();
		List<Prioridade> prioridadeList = new ArrayList<Prioridade>();
		prioridadeList = DAO.getInstance().list(Prioridade.class);
		for (Prioridade item : prioridadeList) {
			prioridades.add(new SelectItem(item.getCodigo(), item
					.getDescricao()));
		}
		return prioridades;
	}

	public void buscarUsuarioLogado() throws IOException, ParseException {
		chamado.setUsuario(new Usuario());
		Usuario usuarioAutenticado = (Usuario) FacesContext
				.getCurrentInstance().getExternalContext().getSessionMap()
				.get("usuarioLogado");
		chamado.setUsuario(usuarioAutenticado);
	}

	public void buscarResponsavelLogado() throws IOException, ParseException {
		chamado.setResponsavel(new Responsavel());
		Responsavel responsavelAutenticado = (Responsavel) FacesContext
				.getCurrentInstance().getExternalContext().getSessionMap()
				.get("responsavelLogado");
		chamado.setResponsavel(responsavelAutenticado);
	}

	public void abrirPesquisar() throws IOException, ParseException {
		chamadoList = new ArrayList<Chamado>();
		chamado = new Chamado();
		chamado.setDepartamento(new Departamento());
		chamado.setCategoria(new Categoria());
		chamado.setResponsavel(new Responsavel());
		chamado.setStatus(new Status());
		chamado.setUsuario(new Usuario());
		chamado.setPrioridade(new Prioridade());
		listarDepartamentos();
		buscarResponsavelLogado();
		listarStatus();
		listarDepartamentos();
		FacesContext.getCurrentInstance().getExternalContext()
				.redirect("pesquisarChamado.jsp");
	}

	public List<Chamado> pesquisar() throws IOException,
			NoSuchAlgorithmException {
		List<Chamado> chamadoListAuxiliar = new ArrayList<Chamado>();
		chamadoList = new ArrayList<Chamado>();
		chamadoList = ChamadoDAO.getInstance().pesquisar(chamado);
		List<ResponsavelDepartamento> responsavelDepartamentosList = new ArrayList<ResponsavelDepartamento>();
		responsavelDepartamentosList = ResponsavelDepartamentoDAO.getInstance()
				.buscarDepartamentos(chamado.getResponsavel());
		if (!chamadoList.isEmpty()) {
			for (Chamado itemChamado : chamadoList) {
				for (ResponsavelDepartamento itemRespDepar : responsavelDepartamentosList) {
					if (itemChamado
							.getDepartamento()
							.getCodigo()
							.equals(itemRespDepar.getDepartamento().getCodigo())) {
						chamadoListAuxiliar.add(itemChamado);
					}
				}
			}
			chamadoList = new ArrayList<Chamado>();
			chamadoList.addAll(chamadoListAuxiliar);
		}
		return chamadoList;
	}

	public void resolver() throws Exception {
		chamado.setDataFim(new Date());
		chamado.setStatus((Status) DAO.getInstance().refresh(
				chamado.getStatus()));
		DAO.getInstance().update(chamado);
		EnviarEmail e = new EnviarEmail();
		e.enviarEmailChamado(chamado);
		chamado = new Chamado();
		chamado.setDepartamento(new Departamento());
		chamado.setCategoria(new Categoria());
		chamado.setResponsavel(new Responsavel());
		chamado.setStatus(new Status());
		chamado.setUsuario(new Usuario());
		chamado.setPrioridade(new Prioridade());
	}

	public void encaminhar() throws Exception {
		chamado.setNivel(Constantes.NIVEL_DOIS);
		chamado.setCategoria(null);
		chamado.getStatus().setCodigo(Constantes.STATUS_AGUARDANDO);
		DAO.getInstance().update(chamado);
		chamado = new Chamado();
		chamado.setDepartamento(new Departamento());
		chamado.setCategoria(new Categoria());
		chamado.setResponsavel(new Responsavel());
		chamado.setStatus(new Status());
		chamado.setUsuario(new Usuario());
		chamado.setPrioridade(new Prioridade());
	}
	
	public void paint(OutputStream stream, Object object) throws IOException {
		stream.write(chamado.getPrint());
	}

	public void listener(UploadEvent event) throws Exception {
		UploadItem item = event.getUploadItem();
		chamado.setPrint(item.getData());
	}
	

}
